//
//  CellViewModel.swift
//  新浪微博项目
//
//  Created by 王炯 on 16/7/23.
//  Copyright © 2016年 王炯. All rights reserved.
//

import UIKit

//定义一个专为Cell服务的ViewModel
//作用:获取到外界的DataModel数据之后，做数据处理，把处理好的数据返回给Cell信息
class CellViewModel: NSObject
{
    
    //设置一个DataModel数据属性
    var dataModel:HomeDataModel?
    
    //保存处理好的一些数据属性
    // 微博认证用户图片
    var avatarImage: UIImage?
    //处理会员等级图片
    var memberImage: UIImage?
    
    //处理微博来源富文本
    var sourceAttr:NSMutableAttributedString?
    
    //处理转发数文本
    var retweetStr:String?
    //处理评论数文本
    var commentStr:String?
    //处理点赞数文本
    var likeStr:String?
    
    //处理微博创建时间(因为微博创建时间随时都会变动，故设置成只读计算属性)
    var weiboTime:String?{
        
        
        return GetSinaTime(dataModel?.created_at ?? "")
        //return GetSinaTime("Tue Jul 26 21:11:53 +0800 2016")
        
    }
    
    
    //处理正文文本生成的富文本
    var weiBoOriginalAttributedStr:NSMutableAttributedString?
    
    //处理转发文本生成的富文本
    var retweetAttributedStr:NSMutableAttributedString?
    
    
    
    
    //根据外面获取到的DataModel数据来初始化CellViewModel对象
    init(dataModel:HomeDataModel)
    {
        super.init()
        
        self.dataModel = dataModel
        
        //返回处理好的数据信息
        // 在viewModel调用重载构造函数初始化的时候 我们要对avatarImage&memberImage 赋值
        self.avatarImage = getAvatarImage(dataModel.user?.verified)
        self.memberImage = getMemberImage(dataModel.user?.mbrank)
        //来源富文本
        self.sourceAttr = getSouceAttr(dataModel.source)
        //转发文本
        
        self.retweetStr = getSinaCount(dataModel.reposts_count, title: "转发")
        //评论文本
        self.commentStr = getSinaCount(dataModel.comments_count, title: "评论")
        //赞文本
        self.likeStr = getSinaCount(dataModel.attitudes_count, title: "赞")
        
        //正文文本的富文本
        self.weiBoOriginalAttributedStr = DealContentText(dataModel.text)
        
        //转发文本的富文本
        self.retweetAttributedStr = DealContentText(dataModel.retweeted_status?.text)
        
        
        
    }
}
//在此扩展内对dataModel的数据进行一些处理，返回处理之后的结果
extension CellViewModel
{
    //1-处理微博认证用户图片/// 认证类型 -1：没有认证，1，认证用户，2,3,5: 企业认证，220: 达人
    func getAvatarImage(verified: Int?) -> UIImage?
    {
        // 判读他是否为nil
        guard let ver = verified else{
            return nil
        }
        
        switch ver {
        case 1:
            return UIImage(named: "avatar_vip")
        case 2,3,5:
            return UIImage(named: "avatar_enterprise_vip")
        case 220:
            return UIImage(named: "avatar_grassroot")
        default:
            return UIImage(named: "avatar_vgirl")
        }
    }

    //2-处理微博会员图片:会员等级:1-6
    func getMemberImage(mbrank: Int?) -> UIImage?
    {
        // 判断他是否为nil
        guard let mbr = mbrank else
        {
            return nil
        }
        if mbr > 0 && mbr < 7
        {
            return UIImage(named: "common_icon_membership_level\(mbr)")
        }
        return UIImage(named: "common_icon_membership")
    }
    //3-处理微博来源
    func getSouceAttr(source:String?) -> NSMutableAttributedString
    {
        
        //判断source是不是字符串且字符串中有没有"\">"字符串
        guard let sour = source where sour.containsString("\">") else
        {
            return getStrAttr("来自")
        }
        
        //因为到这个位置就可以确定字符串中含有这两个字符，故可以强行解包
        //字符截取的起始位置
        let startStr = sour.rangeOfString("\">")!
        
        //字符截取的结束位置
        let endStr = sour.rangeOfString("</")!
        
        //根据起始位值和结束位置截取字符串
        let resultStr = sour.substringWithRange(startStr.endIndex..<endStr.startIndex)

        
        return getStrAttr("来自" + resultStr)
    }
    
    
    //3.2 根据传入的字符串生成特定的富文本字符串
    func getStrAttr(str:String) -> NSMutableAttributedString
    {
        
        //初始化一个富文本
        let attrStr:NSMutableAttributedString = NSMutableAttributedString(string: str)
        
        //得到range(将string类型转换成NSString）
        let range:NSRange = (str as NSString).rangeOfString("来自")
        
        
        //利用range设置富文本的属性
        attrStr.setAttributes([NSForegroundColorAttributeName: UIColor.grayColor()], range: range)
        
        return attrStr
    }
    
    
    //4-处理微博转发评论赞的业务逻辑
    /*
     - 转发 评论 赞 业务逻辑处理
     - 如果count <= 0  显示 转发 评论 赞 例如 0  显示 转发 评论 赞
     - 如果count > 0
     - 如果 count < 10000  数据是多少显示多少  例如  8888  显示 8888
     - 如果 count >= 10000  显示 x.x万       例如 12000  显示 1.2 万
     - 注意 如果 count%10000 = 0  显示  例如 20000 显示 2万
     */
    func getSinaCount(count:Int,title:String) -> String
    {
        //print("\(title)数是\(count)")
        //小于零时，显示当前文本
        if count <= 0
        {
            return title
        }
        else
        {
            if count < 10000
            {
                return "\(count)"
            }
            else
            {
                
                let num = CGFloat(count / 1000) / 10
                
                var numStr = "\(num)万"
                
                //如果numStr中包含".0"，则把".0"替换成空格""
                if numStr.containsString(".0")
                {
                    
                    //字符串替换
                    numStr = numStr.stringByReplacingOccurrencesOfString(".0", withString: "")
                }
                return numStr
            }
        }
    }
    
    //5-处理微博创建时间的方法
    /*
      时间处理逻辑:
     //    - 如果是今年
     //
     //    - 如果是今天
     //    - 小于60秒 显示 刚刚
     //    - 大于等于60秒且小于3600秒  显示 xx分钟前
     //    - 大于等于3600秒  显示  xx小时前
     //
     //    - 如果是昨天
     //    - 例如 2016-07-25 10:10:10  显示格式 昨天 10:10
     //
     //    - 如果是其他
     //    - 例如 2016-05-01 10:10:10  显示格式 05月01日 10:10
     //
     //    - 如果不是今年
     //    - 例如 2015-01-01 10:10:10
     //    - 显示 格式: 2015年01月01日 10:10
     */
    func GetSinaTime(createTime:String) -> String
    {
        //获取到的时间格式如下
        // Tue Jul 26 11:11:53 +0800 2016
        //如果时间为空，返回""
        if createTime == ""
        {
            return ""
        }
        //(1)初始化一个时间格式
        let df = NSDateFormatter()
        //设置locate 指定地区(美国???) 如果不指定 在真机中时间会有问题
        df.locale = NSLocale(localeIdentifier: "en_US")
        // 指定格式(格式按照从网络获取到的时间格式爱来写)
        df.dateFormat = "EEE MMM dd HH:mm:ss z yyyy"
        // 获取微博的日期(NSDate对象)
        let sinaDate = df.dateFromString(createTime)!
        
        //(1)判断是否是同一年的
        if isThisYear(sinaDate)
        {
            
            //利用NSCalender类来判断是不是同一天
            //声明一个当前的时间的日历类
            let currentCalender:NSCalendar = NSCalendar.currentCalendar()
            
            //(2)利用currentCalender来判断是不是今天
            if currentCalender.isDateInToday(sinaDate)
            {
                
                // 获取当前时间和传入的微博时间差值(以秒为单位)
                let s = Int(NSDate().timeIntervalSinceDate(sinaDate))
                //print(s)
                //(3)判断是不是在60s内
                if s < 60
                {
                    return "刚刚"
                }
                //(4)判断是不是在1小时内
                else if s >= 60 && s < 3600
                {
                    return "\(s/60)分钟前"
                }
                //(5)判断是不是在24小时内
                else
                {
                    return "\(s/3600)小时前"
                }
            }
            //判断是不是昨天
            else if currentCalender.isDateInYesterday(sinaDate)
            {
                //重新指定的时间格式
                df.dateFormat = "HH:mm"
                
                //利用重新指定的时间格式把NSDate转换成String
                let weiboDateStr = df.stringFromDate(sinaDate)
                
                return "昨天 \(weiboDateStr)"
            }
            //其他天数时间
            else
            {
                //重新指定的时间格式
                df.dateFormat = "MM月dd日 HH:mm"
                
                //利用重新指定的时间格式把NSDate转换成String
                let weiboDateStr = df.stringFromDate(sinaDate)
                
                return weiboDateStr
            }
        }
        //不是同一年的
        else
        {
            //重新指定的时间格式
            df.dateFormat = "yyyy年MM月dd日 HH:mm"
            
            //利用重新指定的时间格式把NSDate转换成String
            let weiboDateStr = df.stringFromDate(sinaDate)
            
            return weiboDateStr
        }
    }
    
    //5.1-判断当前时间是不是今年的(利用格式化时间的模式)
    func isThisYear(date:NSDate) -> Bool
    {
        
        //(1)初始化一个时间格式
        let df = NSDateFormatter()
        //设置locate 指定地区(美国???) 如果不指定 在真机中时间会有问题
        df.locale = NSLocale(localeIdentifier: "en_US")
        // 指定格式(判断年则只显示年)
        df.dateFormat = "yyyy"
        
        //(2)按照这个时间格式来规范当前的时间(利用NSDate来返回String）
        let currentDate = NSDate()
        
        let currentYearStr = df.stringFromDate(currentDate)
        
        //(3)按照这个时间格式来规范传入来的时间(利用NSDate来返回String）
        let weiboYearStr = df.stringFromDate(date)
        
        
        //(4)返回两个年份是否相等
        return currentYearStr == weiboYearStr
    }
    
    
    //6利用正则表达式的思想处理正文中有关表情的富文本数据
    func DealContentText(contentText:String?) -> NSMutableAttributedString?
    {
        //(1)判断是否有值
        guard let text = contentText else
        {
            return nil
        }
        
        
        //(2)根据微博的正文获取得到一个富文本
        let allAttr = NSMutableAttributedString(string:text)
        
        
        
        
        
        //(3)定义正则格式(取[]中的所有文本数据信息,也包括中括号符[]：包括大小写字母和数字和汉字)
        //汉字编码信息:\\u4e00-\\u9fa5
        let regex = "\\[[a-zA-Z0-9\\u4e00-\\u9fa5]+\\]"
        
        //(4)创建一个临时可变数组,用于存放当期的字符串中所有的匹配字符串的模型(匹配结果+匹配范围)
        var tempArray:[MatchResult] = [MatchResult]()
        
        
        
        //(5)遍历字符串
        /*
         -01 匹配的个数（count == 1_)
         -02 匹配的结果（指针）
         -03 匹配的范围（指针）
         -04 匹配是否停止
         */
        //同一个字符串下当有多次匹配时就会多次调用以下方法
        //当每次匹配正则表达式就会每次调用以下方法
        (text as NSString).enumerateStringsMatchedByRegex(regex){(count, string, range, _) -> Void in
            
            //print("\(text)中\n    (1)适合正则表达式的正文中的个数:\(count)\n(2)正文中匹配的结果:\(string.memory)\n(3)匹配的范围:\(range.memory)")
            
            //根据匹配结果和匹配范围生成匹配的模型
            let resultModel:MatchResult = MatchResult(string:string.memory as? String, range: range.memory)
            
            //添加到数组中
            tempArray.append(resultModel)
        }
        
        
        //注意：一定要倒着遍历匹配模型数组！！！！,因为正向遍历模型数组时，其range可能会改变(当一个字符串中有多个匹配的字符串时)
        for resultModel in tempArray.reverse()
        {
            //字符指针--->字符串：string.memory as? String
            let model = EmotionDataTool.sharedTool.SearchPng((resultModel.result))
            
            //判断Model是否为nil
            guard let mode = model else
            {
                //继续下一次
                continue
            }
            
            
            //(5)初始化并设置文本附件
            //2.1 初始化附件
            let att = MyTextAttachment()
            
            //2.2 设置附件image
            att.image = UIImage(named:mode.path ?? "", inBundle: EmotionDataTool.sharedTool.emotionBundle, compatibleWithTraitCollection: nil)
            
            //2.3 设置附件的bounds(一定要)
            //获取textView文本的字体高度
            let lineHeight = UIFont.systemFontOfSize(15).lineHeight
            
            //设置y坐标为-4是相对于textView的正常文本位置的y坐标而言向下低于4个位置)
            att.bounds = CGRect(x: 0, y: -4, width: lineHeight, height: lineHeight)
            
            //2.4 利用附件创建一个不可变的富文本
            let attr = NSAttributedString(attachment: att)
            
            //2.5设置附件的model
            att.model = model
            
            //(6)利用repalce方法重新设置总富文本
            allAttr.replaceCharactersInRange(resultModel.range, withAttributedString: attr)
        }
        
        return allAttr
    }
    
    

}